package com.fupeng.thoughtworks;

import org.junit.Test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by lecky on 2016/9/20 0020.
 */
public class Solution {

    @Test
    public void test() {
        String target = "e4e87cb2-8e9a-4749-abb6-26c59344dfee\n" +
                "2016/09/02 22:30:46\n" +
                "cat1 10 9\n\n" +
                "351055db-33e6-4f9b-bfe1-16f1ac446ac1\n" +
                "2016/09/02 22:30:52\n" +
                "cat1 10 9 2 -1\n" +
                "cat2 2 3\n\n" +
                "dcfa0c7a-5855-4ed2-bc8c-4accae8bd155\n" +
                "2016/09/02 22:31:02\n" +
                "cat1 12 8 3 4\n\n";
        System.out.println(getSnapShot(target, "dcfa0c7a-5855-4ed2-bc8c-4accae8bd155"));
    }

    /**
     * 实现根据id，从historyData中提取当前id表示时刻的动物坐标
     *
     * @param historyData
     * @param id
     * @return
     */
    public String getSnapShot(String historyData, String id) {
        Map<String, Animal> animalMap = new HashMap<>();
        String validate = validate(historyData, id,animalMap);
        if (null == validate)
            return getResult(id,animalMap);
        else
            return validate;
    }

    /**
     * 获得结果
     *
     * @param id
     * @param animalMap
     * @return
     */
    private String getResult(String id, Map<String, Animal> animalMap) {
        Queue<String> queue = new PriorityQueue<>();
        StringBuilder result = new StringBuilder();
        for(String str:animalMap.keySet())
            queue.offer(str);
        while(!queue.isEmpty()){
            Animal animal = animalMap.get(queue.remove());
            result.append(animal.getAnimal_id()).append(" ")
                    .append(animal.getX_pos()).append(" ")
                    .append(animal.getY_pos()).append(" ")
                    .append("\n");
        }
        return result.toString();
    }

    /**
     * historyData校验函数
     * 1，校验historyData字符串格式是否正确
     * 2，校验每一个id所表示的快照中动物坐标是否正确
     *
     * @param historyData
     * @param id
     * @param animalMap
     * @return若没有问题，则返回null，否则返回具体的问题
     */
    private String validate(String historyData,String id, Map<String, Animal> animalMap) {
        if (historyData == null)
            return "Invalid format.";
        //获取每一份快照的数组
        String[] target = historyData.split("\n\n");
        Map<String,Animal> allAnimalMap = new HashMap<>();
        for (String str : target) {
            //获取每一个快照内部数据
            String[] snapStr = str.split("\n");
            if (snapStr[0] == null || snapStr[0] == "" || snapStr[0].indexOf(" ") > -1)
                return "Invalid format.";
            if (!isvalidDate(snapStr[1]) || snapStr.length <= 2)
                return "Invalid format.";
            Snap snap = new Snap();
            snap.setId(snapStr[0]);
            snap.setTime(snapStr[1]);
            for (int index = 2; index < snapStr.length; index++) {
                Animal animal;
                try {
                    animal = new Animal(snapStr[index]);
                }catch (NumberFormatException e){
                    return "Invalid format.";
                }
                if (!allAnimalMap.containsKey(animal.getAnimal_id())) {
                    allAnimalMap.put(animal.getAnimal_id(), animal);
                } else {
                    Animal animalInMap = allAnimalMap.get(animal.getAnimal_id());
                    if (animal.checkData(animalInMap)) {
                        animalInMap.setX_pos(animal.getX_pos() + animal.getX_move());
                        animalInMap.setY_pos(animal.getY_pos() + animal.getY_move());
                    } else {
                        return "Conflict found at " + id;
                    }
                }
                snap.getList().add(animal);
            }
            if(snap.getId().equals(id)){
                animalMap.putAll(allAnimalMap);
            }
        }
        return null;
    }


    /**
     * 日期格式校验
     * @param s
     * @return
     */
    private  boolean isvalidDate(String s) {
        boolean convertSuccess=true;
        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        try {
            format.setLenient(false);
            format.parse(s);
        }catch (ParseException e){
            convertSuccess = true;
        }
        return convertSuccess;
    }

}
